<?php
/**
 * 精简节假日API
 * @copyright tool.bitefu.net
 * @author xiaogg@sina.cn
 */
class DateApi
{
    // 数据存储路径
    private $dataPath = 'data/';
    // 静态年份数据缓存
    private static $yearDataCache = array();
    
    /**
     * 构造函数 - 预加载当前年份数据
     */
    public function __construct()
    {
        // 预加载当前年份数据
        $currentYear = date('Y');
        $this->getYearData($currentYear);
    }
    /**
     * 获取一天的节假日情况
     * @param string $day 日期如 20250101 或 2025-01-01
     * @param int $type 类型 1工资倍数【0：工作日 1：周未双倍工资 2：假日三倍工资】,2具体类型【1 工作日 2调休(工作日) 3周未 4假日】
     * @return array 返回结果数组
     */
    public function getday($day, $type = 1)
    {
        // 验证日期格式
        if (!$this->validateDate($day)) {
            return array('status' => 0, 'info' => '日期格式错误');
        }
        // 清理日期格式
        $day = str_replace('-', '', $day);
        // 获取年份
        $year = substr($day, 0, 4);
        // 获取年份数据
        $yearData = $this->getYearData($year);
        if ($yearData === false) {
            return array('status' => 0, 'info' => '数据获取失败');
        }
        // 获取节假日信息
        $holidayData = $this->getHolidayInfo($day, $yearData);
        // 根据类型返回结果
        if ($type == 2) {
            $data = $this->getDetailType($day, $holidayData);
        } else {
            $data = $this->getWageMultiplier($day, $holidayData);
        }
        return array('status' => 1, 'info' => $data);
    }
    /**
     * 检查是否是周末
     * @param string $day 日期
     * @return int 1是周末，0不是
     */
    private function checkWeekend($day)
    {
        // 使用DateTime对象，避免重复调用strtotime
        $date = DateTime::createFromFormat('Ymd', $day);
        if (!$date) {
            $date = DateTime::createFromFormat('Y-m-d', $day);
        }
        
        $weekday = (int)$date->format('N');
        return ($weekday >= 6) ? 1 : 0;
    }
    /**
     * 验证日期格式
     * @param string $date 日期
     * @return bool 是否有效
     */
    public function validateDate($date, $format=null) {
        if(empty($date) || strlen($date) < 8) return false;
        
        // 对于纯数字格式，直接使用固定格式验证
        if(is_numeric($date)) {
            $d = DateTime::createFromFormat('Ymd', $date);
            return $d && $d->format('Ymd') === $date;
        }
        
        // 对于带分隔符的格式，使用Y-m-d验证
        $d = DateTime::createFromFormat('Y-m-d', $date);
        return $d && $d->format('Y-m-d') === $date;
    }
    /**
     * 获取一年的数据
     * @param string $year 年份
     * @return array|false 年份数据或false
     */
    private function getYearData($year)
    {
        // 检查静态缓存
        if (isset(self::$yearDataCache[$year])) {
            return self::$yearDataCache[$year];
        }
        // 本地文件路径
        $filePath = $this->dataPath . $year . '_data.json';
        // 检查本地文件是否存在
        if (file_exists($filePath)) {
            $data = json_decode(file_get_contents($filePath), true);
            if ($data !== null) {
                self::$yearDataCache[$year] = $data;
                return $data;
            }
        }
        // 远程获取数据
        $url = 'https://gitee.com/web/holidays_api/raw/master/data/' . $year . '_data.json';
        $content = @file_get_contents($url);
        if ($content !== false) {
            $data = json_decode($content, true);
            if ($data !== null) {
                // 保存到本地
                file_put_contents($filePath, $content); // 直接保存原始内容，避免重新编码
                self::$yearDataCache[$year] = $data;
                return $data;
            }
        }
        return false;
    }
    /**
     * 获取节假日信息
     * @param string $day 日期
     * @param array $yearData 年份数据
     * @return int|null 节假日信息
     */
    private function getHolidayInfo($day, $yearData)
    {
        if (!$yearData) {
            return null;
        }
        
        $monthDay = substr($day, 4, 4);
        return isset($yearData[$monthDay]) && is_numeric($yearData[$monthDay]) ? $yearData[$monthDay] : null;
    }
    /**
     * 获取详细类型
     * @param string $day 日期
     * @param mixed $holidayData 节假日数据
     * @return int 类型
     */
    private function getDetailType($day, $holidayData)
    {
        if (is_numeric($holidayData)) {
            return $holidayData > 0 ? 4 : 2;
        }
        return $this->checkWeekend($day) ? 3 : 1;
    }
    /**
     * 获取工资倍数
     * @param string $day 日期
     * @param mixed $holidayData 节假日数据
     * @return int 工资倍数
     */
    private function getWageMultiplier($day, $holidayData)
    {
        return is_numeric($holidayData) ? $holidayData : $this->checkWeekend($day);
    }
}
?>